{% extends "layout/basic.html" %}
{% block content %}
<div class="typepractice">
<link rel="stylesheet" href="/typepractice.css?_={{ Date.now() }}" />
<h1 class="typepractice-title">键盘打字练习</h1>
    
    <div class="typepractice-stats">
        <div class="typepractice-stat-box">
            <h3>准确率</h3>
            <p id="accuracy">0%</p>
        </div>
        <div class="typepractice-stat-box">
            <h3>错误率</h3>
            <p id="error-rate">0%</p>
        </div>
        <div class="typepractice-stat-box">
            <h3>速度 (字符/分)</h3>
            <p id="speed">0</p>
        </div>
        <div class="typepractice-stat-box">
            <h3>已打字符</h3>
            <p id="total-chars">0</p>
        </div>
    </div>
    
    <div class="typepractice-timer" id="timer">剩余时间：5:00</div>
    
    <div class="typepractice-target-char" id="target-char"></div>
    
    <div class="typepractice-keyboard-container">
        <div class="typepractice-keyboard-row">
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">!</span>
                <span class="typepractice-lower-char">1</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">@</span>
                <span class="typepractice-lower-char">2</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">#</span>
                <span class="typepractice-lower-char">3</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">$</span>
                <span class="typepractice-lower-char">4</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">%</span>
                <span class="typepractice-lower-char">5</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">^</span>
                <span class="typepractice-lower-char">6</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">&</span>
                <span class="typepractice-lower-char">7</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">*</span>
                <span class="typepractice-lower-char">8</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">(</span>
                <span class="typepractice-lower-char">9</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">)</span>
                <span class="typepractice-lower-char">0</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">_</span>
                <span class="typepractice-lower-char">-</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">+</span>
                <span class="typepractice-lower-char">=</span>
            </div>
            <div class="typepractice-keyboard-key typepractice-delete-key">Backspace</div>
        </div>
        
        <div class="typepractice-keyboard-row">
            <div class="typepractice-keyboard-key">
                <span>Q</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>W</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>E</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>R</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>T</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>Y</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>U</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>I</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>O</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>P</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">{</span>
                <span class="typepractice-lower-char">[</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">}</span>
                <span class="typepractice-lower-char">]</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">|</span>
                <span class="typepractice-lower-char">\</span>
            </div>
        </div>
        
        <div class="typepractice-keyboard-row">
            <div class="typepractice-keyboard-key">
                <span>A</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>S</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>D</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>F</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>G</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>H</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>J</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>K</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>L</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">:</span>
                <span class="typepractice-lower-char">;</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">"</span>
                <span class="typepractice-lower-char">'</span>
            </div>
            <div class="typepractice-keyboard-key typepractice-enter-key">Enter</div>
        </div>
        
        <div class="typepractice-keyboard-row">
            <div class="typepractice-keyboard-key typepractice-shift-key typepractice-span-2">
                Shift ⇧
            </div>
            <div class="typepractice-keyboard-key">
                <span>Z</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>X</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>C</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>V</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>B</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>N</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span>M</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char"><</span>
                <span class="typepractice-lower-char">,</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">></span>
                <span class="typepractice-lower-char">.</span>
            </div>
            <div class="typepractice-keyboard-key">
                <span class="typepractice-lower-char">?</span>
                <span class="typepractice-lower-char">/</span>
            </div>
            <div class="typepractice-keyboard-key typepractice-shift-key typepractice-span-2">
                Shift ⇧
            </div>
        </div>
        
        <div class="typepractice-keyboard-row">
            <div class="typepractice-keyboard-key typepractice-space-key">Space</div>
        </div>
    </div>
    
    <div class="typepractice-control-row">
        <button id="start-btn">开始练习</button>
    </div>
    
    <div class="typepractice-instructions">
        <h3>使用说明：</h3>
        <p>1. 点击"开始练习"按钮开始</p>
        <p>2. 顶部会显示一个随机字符</p>
        <p>3. 在键盘上找到对应的键并按下</p>
        <p>4. 大写字母和特殊字符需要同时按Shift键</p>
        <p>5. 练习时间为5分钟，倒计时结束后自动停止</p>
    </div>
</div>
<script>
        // 用于存储键盘按键元素
        let keyboardKeys = {};
        
        // 存储练习统计数据
        let stats = {
            correct: 0,
            incorrect: 0,
            total: 0,
            startTime: null,
            currentTime: null
        };
        
        // 是否在练习中
        let isPracticing = false;
        
        // 当前需要输入的目标字符
        let currentTarget = null;
        
        // 练习时间（5分钟）
        const practiceDuration = 5 * 60 * 1000; // 毫秒
        let timerInterval = null;
        
        // 需要显示Shift提示的字符
        const shiftChars = ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '{', '}', '|', ':', '"', '<', '>', '?'];
        
        // 大写字母
        const upperChars = [...Array(26).keys()].map(i => String.fromCharCode(65 + i));
        
        // 小写字母
        const lowerChars = [...Array(26).keys()].map(i => String.fromCharCode(97 + i));
        
        // 数字
        const numbers = [...Array(10).keys()].map(i => i.toString());
        
        // 初始化键盘
        function initKeyboard() {
            const keyElements = document.querySelectorAll('.typepractice-keyboard-key');
            keyElements.forEach(key => {
                const keyText = key.textContent.replace(/\s/g,"");
                if(keyText.length <= 2)
                for(let i = 0; i < keyText.length;i++)
                    keyboardKeys[keyText[i]] = key;
                
                // 点击键盘上的键也可以输入
                key.addEventListener('click', () => {
                    if (!isPracticing) return;
                    
                    const pressedKey = keyText;
                    checkInput(pressedKey);
                });
            });
        }
        
        // 开始练习
        function startPractice() {
            isPracticing = true;
            stats = {
                correct: 0,
                incorrect: 0,
                total: 0,
                startTime: Date.now(),
                currentTime: Date.now()
            };
            
            updateStats();
            showNextTarget();
            
            // 设置定时器
            timerInterval = setInterval(updateTimer, 1000);
            
            document.getElementById('start-btn').disabled = true;
            console.log("练习已开始");
        }
        
        // 更新倒计时
        function updateTimer() {
            const elapsedTime = Date.now() - stats.startTime;
            const remainingTime = practiceDuration - elapsedTime;
            
            if (remainingTime <= 0) {
                stopPractice();
                clearInterval(timerInterval);
                return;
            }
            
            const minutes = Math.floor(remainingTime / 60000);
            const seconds = Math.floor((remainingTime % 60000) / 1000);
            
            document.getElementById('timer').textContent = `剩余时间：${minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
        }
        
        // 停止练习
        function stopPractice() {
            isPracticing = false;
            currentTarget = null;
            
            // 清除定时器
            clearInterval(timerInterval);
            
            // 隐藏所有高亮和错误标记
            for (let key in keyboardKeys) {
                keyboardKeys[key].classList.remove('active');
                keyboardKeys[key].classList.remove('wrong');
            }
            
            // 更新最终统计数据
            updateStats();
            
            document.getElementById('start-btn').disabled = false;
            console.log("练习已停止");
        }
        
        // 显示下一个目标字符
        function showNextTarget() {
            const chars = [...lowerChars, ...upperChars]; // 包含大小写字母
            const symbols = [...numbers, ...shiftChars]; // 包含数字和特殊字符
            
            // 合并所有字符，去除重复
            const allChars = [...new Set([...chars, ...symbols])];
            
            // 随机选择一个字符
            const randomIndex = Math.floor(Math.random() * allChars.length);
            currentTarget = allChars[randomIndex];
            
            // 显示目标字符
            document.getElementById('target-char').textContent = currentTarget;
            
            // 高亮显示对应的键盘按键
            highlightTargetKey(currentTarget);
            
            // 重置stats中的当前时间
            stats.currentTime = Date.now();
        }
        
        // 高亮显示目标按键
        function highlightTargetKey(target) {
            // 先清除所有高亮
            for (let key in keyboardKeys) {
                keyboardKeys[key].classList.remove('active');
                keyboardKeys[key].classList.remove('wrong');
            }
            
            // 如果需要按Shift键，则高亮Shift键
            if (shiftChars.includes(target) || upperChars.includes(target)) {
                document.querySelectorAll('.typepractice-keyboard-key.typepractice-shift-key').forEach(shiftKey => {
                    shiftKey.classList.add('active');
                });
                
                // 将Shift提示设置为临时的，之后消失
                setTimeout(() => {
                    document.querySelectorAll('.typepractice-keyboard-key.typepractice-shift-key').forEach(shiftKey => {
                        shiftKey.classList.remove('active');
                    });
                }, 1000);
            }
            
            // 高亮显示目标键
            let keyToHighlight = target;
            
            // 对于小写字母，高亮显示对应的大写字母键
            if (lowerChars.includes(target)) {
                keyToHighlight = target.toUpperCase();
            }
            
            if (keyboardKeys[keyToHighlight]) {
                keyboardKeys[keyToHighlight].classList.add('active');
            }
        }
        
        // 检查输入
        function checkInput(input) {
            if (!isPracticing || !currentTarget) return;
            
            // 获取Shift键状态
            const isShiftPressed = input === 'Shift⇧' || (event && event.getModifierState('Shift'));
            
            // 真实输入的字符（考虑Shift状态）
            let actualInput = input;
            if(isShiftPressed && input.length > 1) return;
            
            // 处理Shift状态
            if (input.length === 1) {
                if (isShiftPressed) {
                    actualInput = input.toUpperCase();
                } else {
                    actualInput = input.toLowerCase();
                }
            }
            
            // 需要Shift的情况（对于大写字母和特殊字符）
            if (upperChars.includes(currentTarget) || shiftChars.includes(currentTarget)) {
                // 如果没有按Shift键，则算作错误
                if (!isShiftPressed) {
                    stats.incorrect++;
                    stats.total++;
                    
                    // 显示错误
                    document.getElementById('target-char').style.color = '#e74c3c';
                    if (keyboardKeys[currentTarget]) {
                        keyboardKeys[currentTarget].classList.add('wrong');
                    }
                    
                    setTimeout(() => {
                        document.getElementById('target-char').style.color = '#e74c3c';
                        if (keyboardKeys[currentTarget]) {
                            keyboardKeys[currentTarget].classList.remove('wrong');
                        }
                    }, 500);
                    
                    updateStats();
                    return;
                }
                
                // 检查是否正确输入了带Shift的字符
                if (actualInput !== currentTarget) {
                    stats.incorrect++;
                    stats.total++;
                    
                    // 显示错误
                    document.getElementById('target-char').style.color = '#e74c3c';
                    if (keyboardKeys[currentTarget]) {
                        keyboardKeys[currentTarget].classList.add('wrong');
                    }
                    
                    setTimeout(() => {
                        document.getElementById('target-char').style.color = '#e74c3c';
                        if (keyboardKeys[currentTarget]) {
                            keyboardKeys[currentTarget].classList.remove('wrong');
                        }
                    }, 500);
                    
                    updateStats();
                    return;
                }
            } else {
                // 检查是否按了Shift键（不需要时）
                if (isShiftPressed && actualInput !== currentTarget) {
                    stats.incorrect++;
                    stats.total++;
                    
                    // 显示错误
                    document.getElementById('target-char').style.color = '#e74c3c';
                    if (keyboardKeys[currentTarget]) {
                        keyboardKeys[currentTarget].classList.add('wrong');
                    }
                    
                    setTimeout(() => {
                        document.getElementById('target-char').style.color = '#e74c3c';
                        if (keyboardKeys[currentTarget]) {
                            keyboardKeys[currentTarget].classList.remove('wrong');
                        }
                    }, 500);
                    
                    updateStats();
                    return;
                }
            }
            
            // 检查是否正确输入字符
            if (actualInput === currentTarget) {
                stats.correct++;
                stats.total++;
                
                // 显示正确输入
                if (keyboardKeys[currentTarget]) {
                    keyboardKeys[currentTarget].classList.add('active');
                    
                    setTimeout(() => {
                        keyboardKeys[currentTarget].classList.remove('active');
                    }, 100);
                }
                
                // 显示下一个目标
                setTimeout(showNextTarget, 300);
            } else {
                stats.incorrect++;
                stats.total++;
                
                // 显示错误
                document.getElementById('target-char').style.color = '#e74c3c';
                if (keyboardKeys[currentTarget]) {
                    keyboardKeys[currentTarget].classList.add('wrong');
                }
                
                setTimeout(() => {
                    document.getElementById('target-char').style.color = '#e74c3c';
                    if (keyboardKeys[currentTarget]) {
                        keyboardKeys[currentTarget].classList.remove('wrong');
                    }
                }, 500);
            }
            
            updateStats();
        }
        
        // 更新统计数据
        function updateStats() {
            // 计算准确率
            const accuracy = stats.total > 0 ? Math.round((stats.correct / stats.total) * 100) : 0;
            
            // 计算错误率
            const errorRate = stats.total > 0 ? Math.round((stats.incorrect / stats.total) * 100) : 0;
            
            // 计算打字速度
            const timeElapsed = (stats.currentTime - stats.startTime) / 1000; // 转换为秒
            const speed = timeElapsed > 0 ? Math.round((stats.correct / timeElapsed) * 60) : 0;
            
            // 更新UI
            document.getElementById('accuracy').textContent = `${accuracy}%`;
            document.getElementById('error-rate').textContent = `${errorRate}%`;
            document.getElementById('speed').textContent = speed;
            document.getElementById('total-chars').textContent = stats.total;
        }
        
        // 初始化
        document.addEventListener('DOMContentLoaded', () => {
            initKeyboard();
            
            // 开始按钮事件
            document.getElementById('start-btn').addEventListener('click', startPractice);
            
            // 键盘事件
            document.addEventListener('keydown', (e) => {
                if (!isPracticing) return;
                
                // 获取按键值
                let key = e.key;
                
                // 处理一些特殊键
                if (key === ' ') key = 'Space';
                if (key === 'Enter') key = 'Enter';
                if (key === 'Escape') key = 'Esc';
                if (key === 'Shift') key = 'Shift⇧';
                if (key === 'Backspace') key = 'Backspace';
                
                // 检查输入
                checkInput(key);
            });
        });
    </script>
{% endblock %}
